package cc.rengu.igas.channel.wechat.core.packswitch;

import cc.rengu.igas.channel.wechat.common.constant.WechatTreeNodeConstant;
import cc.rengu.igas.channel.wechat.common.constant.WechatTxnNumConstant;
import cc.rengu.igas.channel.wechat.core.realize.WechatSignService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.FinanceTxnMapper;
import cc.rengu.oltp.service.common.dao.impl.FinanceTxnMapperImpl;
import cc.rengu.igas.channel.wechat.common.constant.WechatParamConstant;
import cc.rengu.igas.channel.wechat.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.wechat.core.realize.impl.WechatSignServiceImpl;
import cc.rengu.jradp.packetswitch.IncomingPackSwitchImpl;
import cc.rengu.jradp.packetswitch.OutgoingPackSwitchImpl;
import cc.rengu.oltp.service.common.entity.FinanceTxn;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.RandomUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

/**
 * 与微信通讯层报文解包前后、组前包后实现类
 * Created by 王成 on 2018/5/31.
 */
public class WechatNotifyPackSwitch implements IncomingPackSwitchImpl, OutgoingPackSwitchImpl {


    @Override
    public byte[] beforeInComPackSwitch(byte[] bytes) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String message = new String(bytes);
        xmlTreeUtil.setXmlTreeStringValue(WechatTreeNodeConstant.MESSAGE, message);
        return bytes;
    }

    @Override
    public int afterInComPackSwitch() throws Exception {
        RgLogger rglog = RgLog.getLogger(this.getClass().getName());
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.INST_ID, AppParamConstant.DEFAULT_INSTID);
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.MSG_SRC_ID, WechatParamConstant.TUNL_ID_WXZF);
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.BIZ_TYPE, AppParamConstant.DEFAULT_BIZ_TYPE);
        xmlTreeUtil.setXmlTreeStringValue(AppParamConstant.SYS_ID, WechatParamConstant.TUNL_ID_WXZF);
        if (xmlTreeUtil.isExist(WechatTreeNodeConstant.WX_ORDER_ID)) {
            xmlTreeUtil.copyStringValue(WechatTreeNodeConstant.WX_ORDER_ID, TreeNodeConstant.FRONT_SEQ_NUM);
        } else {
            String frontSeqNum = WechatParamConstant.PREFIX_SEQ_STRING + DateUtil.getCurrentDate() + DateUtil.getCurrentTime() + RandomUtil.getRandomInt();
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.FRONT_SEQ_NUM, frontSeqNum);
        }
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(WechatTreeNodeConstant.PAY_SEQ_NO);
        /* 获取原交易信息 */
        /* 获取原交易信息 */
        FinanceTxnMapper financeTxnMapper = new FinanceTxnMapperImpl();
        FinanceTxn financeTxn = financeTxnMapper.selectFinanceTxnInfoByPrimaryKey(AppParamConstant.DEFAULT_INSTID, sysSeqNum);
        if (null == financeTxn) {
            rglog.error("根据SYS_SEQ_NUM<{}>查询原交易失败!", sysSeqNum);
            throw new BizException(RespCodeEnum.ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.ORIG_TXN_NOT_FOUND.getRespDesc());
        }
        xmlTreeUtil.setXmlTreeObjectValue(WechatTreeNodeConstant.ORG_TXN_INFO, financeTxn);
        /* 根据通知地址指定内部交易处理码 */
        String urlString = xmlTreeUtil.getXmlTreeStringValue(WechatTreeNodeConstant.DEFINE_HTTP_CLIENT_URL);
        if (urlString.contains("wechat")) {
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, WechatTxnNumConstant.T00CH200);
        }
        xmlTreeUtil.setXmlTreeStringValue(WechatTreeNodeConstant.MCHNT_NO, financeTxn.getMchntNo());

        /* 生成生成数字签名的字符串 */
        String message = xmlTreeUtil.getXmlTreeStringValue(WechatTreeNodeConstant.MESSAGE);
        WechatSignService wechatSignService = new WechatSignServiceImpl();
        String signBlockString = wechatSignService.generateSignBlockString(message);
        if (null == signBlockString) {
            rglog.error("生成加签Block失败!");
            throw new BizException(RespCodeEnum.GENERATE_SIGN_BLOCK_ERROR.getRespCode(), RespCodeEnum.GENERATE_SIGN_BLOCK_ERROR.getRespDesc());
        }
        rglog.debug("微信加签Block:<{}>", signBlockString);
        String sign = xmlTreeUtil.getXmlTreeStringValue(WechatTreeNodeConstant.WX_SIGN);
        boolean verifyFlag = wechatSignService.verifyMD5SignString(sign, signBlockString, "md5key");
        if (!verifyFlag) {
            rglog.error("数字签名验签失败!");
            throw new BizException(RespCodeEnum.VERIFY_SIGN_ERROR.getRespCode(), RespCodeEnum.VERIFY_SIGN_ERROR.getRespDesc());
        }
        xmlTreeUtil.deleteXmlTreeNode(WechatTreeNodeConstant.MESSAGE);
        return 0;
    }

    @Override
    public int beforeOutgoPackSwitch() throws Exception {
        return 0;
    }

    @Override
    public byte[] afterOutgoPackSwitch(byte[] bytes) throws Exception {
        return bytes;
    }
}
